package com.dy.security.config;

import com.dy.security.service.impl.MypersistentTokenRepositoryImpl;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import javax.annotation.Resource;

/**
 * @Author: ding-yu
 * @Date: 2022/5/19 17:24
 * @Desctiption: (描述)
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //持久化令牌方案
    @Resource
    private MypersistentTokenRepositoryImpl tokenRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/api/user/**").hasAnyRole("user")
                .antMatchers("/api/admin/**").hasAnyRole("admin")
                .antMatchers("/api/public/**").permitAll()
                .and()
                .formLogin()
                .and()
                //简单实现记住我
                .rememberMe().userDetailsService(userDetailsService())
                //持久化令牌方案,
                /**
                 * 在持久化令牌方案中，最核心的是series和token两个值，它们都是用MD5散列过的随机字符串。不同的是，series仅在用户使用密码重新登录时更新，而token会在每一个新的session中都重新生成。
                 * 解决了散列加密方案中一个令牌可以同时在多端登录的问题。每个会话都会引发token的更
                 * 新，即每个token仅支持单实例登录。
                 * 自动登录不会导致series变更，而每次自动登录都需要同时验证series和token两个值，当该
                 * 令牌还未使用过自动登录就被盗取时，系统会在非法用户验证通过后刷新 token 值，此时在合法用户
                 * 的浏览器中，该token值已经失效。当合法用户使用自动登录时，由于该series对应的 token 不同，系统
                 * 可以推断该令牌可能已被盗用，从而做一些处理。例如，清理该用户的所有自动登录令牌，并通知该
                 * 用户可能已被盗号等
                 * Spring Security使用PersistentRememberMeToken来表明一个验证实体:
                 */
                .tokenRepository(tokenRepository);
    }
}
